﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCtrl : BaseMono, IOnExplode
{
	public Action OnEnterDoor;

	public bool Enable = false;
	public bool GodMode = false;
	public float CameraHeight = -15;
	public Vector2 input;

	public PathSeeker Seeker;
	public Transform Target;
	public Rigidbody2D Rigidbody2D;
	public Animator Animator;
	public AudioSource Audio;
	public Transform Camera;
	public PlayerFSM FSM;

	private Transform Root;
	private GameObject bomb;

	public PlayerData Data = new PlayerData();
	private int PlaceBombCount;

	public float MoveSpeed {
		get { return 3 + Data.MoveSpeedPlus * 0.5f; }
	}

	public int FireDis
	{
		get { return 1 + Data.FireDisPlus; }
	}

	public int CarryBombNum
	{
		get { return 1 + Data.CarryBombNumPlus; }
	}

	public override void onAwake()
	{
		base.onAwake();

		Root = GameObject.FindWithTag("Root").transform;
		bomb = Resources.Load<GameObject>("Bomb/Prefabs/Bomb");
		Rigidbody2D = GetComponent<Rigidbody2D>();
		Animator = GetComponent<Animator>();
		Audio = gameObject.TryGetComponent<AudioSource>();
		Camera = UnityEngine.Camera.main.transform;

		GameObject go = new GameObject("PlayerFSM");
		go.transform.SetParent(MyTrans);
		FSM = go.AddComponent<PlayerFSM>();

//		Seeker = gameObject.TryGetComponent<PathSeeker>();
//		Seeker.OnFindPath += DrawPath;
	}

	public override void Init()
	{
		base.Init();
		FSM.InitFSM(this);
	}

	public override void onUpdate()
	{
		base.onUpdate();
		GetInput(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")));

		if (!Enable)
		{
			return;
		}
		if (Input.GetKeyDown(KeyCode.Space))
		{
			PlaceBomb();
		}

		CameraMove();
	}

	public override void onFixedUpdate()
	{
		base.onFixedUpdate();
		if (!Enable) {
			return;
		}

//		if (Target)
//		{
//			Seeker.SetPosition(MyTrans.position, Target.position);
//		}
	}

	void OnTriggerEnter2D(Collider2D collider) 
	{
		OnColliderCheck(collider);
	}

	void OnTriggerStay2D(Collider2D collider) {
		OnColliderCheck(collider);
	}

	void OnColliderCheck(Collider2D collider) {
		if (!Enable)
		{
			return;
		}
		if (collider.gameObject.layer.Equals(LayerMask.NameToLayer("Enemy"))) {
			EnemyCtrl ctrl = collider.GetComponent<EnemyCtrl>();
			if (ctrl != null && !ctrl.IsDead) {
				Die();
			}
		} else if (collider.gameObject.layer.Equals(LayerMask.NameToLayer("Prop"))) {
			Prop prop = collider.gameObject.GetComponent<Prop>();

			if (prop != null && prop.Enable) {
				GainProp(prop);
			}
		}
	}

	public void Born()
	{
		Reset();
		FSM.OnIdle();
		MyTrans.position = MainGame.AStarGridMgr.ChooseSpawnPos();
	}

	public void GetInput(Vector2 input)
	{
		this.input = input;

		if (this.input.magnitude > 0)
		{
			FSM.OnMove();
		}
		else
		{
			FSM.OnIdle();
		}
	}

	public void PlaceBomb()
	{
		AStarNode node = AStarGridMgr.grid.GetNodeByWorldPos(MyTrans.position);

		if (node != null && node.CanMove)
		{
			if (PlaceBombCount < CarryBombNum)
			{
				GameObject go = Instantiate(bomb, new Vector3(
					Mathf.RoundToInt(transform.position.x + 0.5f) - 0.5f,
					Mathf.RoundToInt(transform.position.y + 0.5f) - 0.5f,
					Mathf.RoundToInt(transform.position.z)), transform.rotation) as GameObject;
				go.transform.SetParent(Root);

				Bomb b = go.TryGetComponent<Bomb>();
				if (b)
				{
					PlaceBombCount++;

					b.OnBombExplode += () => PlaceBombCount--;
					b.BePlaced(FireDis);
					Audio.PlayOneShot(SoundMgr.Ins.PlaceBomb);
				}
			}
		}
	}

	private void GainProp(Prop prop)
	{
		switch (prop.Info.Type)
		{
			case PropTypy.BombPlus:
				Data.CarryBombNumPlus++;
				prop.SetVisible(false);
				break;
			case PropTypy.FireDisPlus:
				Data.FireDisPlus++;
				prop.SetVisible(false);
				break;
			case PropTypy.SpeedPlus:
				Data.MoveSpeedPlus++;
				prop.SetVisible(false);
				break;
			case PropTypy.Door:
				if (OnEnterDoor != null)
				{
					OnEnterDoor();
				}
				break;
		}
	}

	public void OnExplode()
	{
		Die();
	}

	public void Die()
	{
		if (GodMode)
		{
			return;
		}
		if (Enable)
		{
			Enable = false;
			input = Vector2.zero;
			FSM.OnDie();

			Data.LifeNum--;
			if (Data.LifeNum > 0)
			{
				StartCoroutine(DelayReborn());
			}
			else
			{
				EventMgr.Ins.RaiseEvent(GameState.GameEnd, new object[] {false});
			}
		}
	}

	IEnumerator DelayReborn()
	{
		yield return new WaitForSeconds(3);
		Born();
	}

	void CameraMove()
	{
		float x = Mathf.Clamp(MyTrans.position.x, 9, MainGame.Ins.Col - 9);
		float y = Mathf.Clamp(MyTrans.position.y, 5f, MainGame.Ins.Row - 5f);
		Vector3 pos = new Vector3(x, y, CameraHeight);

		Camera.position = pos;
	}

	public void Reset()
	{
		Enable = true;
		FSM.Reset();
	}

	/// <summary>
	/// 画出路径
	/// </summary>
	/// <param name="node"></param>
	public void DrawPath(List<Vector3> posList) {
		for (int i = 1, length = posList.Count; i < length; i++) {
			Debug.DrawLine(posList[i - 1], posList[i], Color.green, 10);
		}
	}
}
